/**
 * Image button class.
 * Preloads and manages button's images.
 *
 * @author Andrey Anisimov <hercules@inbox.ru>
 * @see core.ui.Button
 */

import core.ui.FocusWindow;

class ImageButton extends FocusWindow {
	
	/**
	 * Creates new image button control.
	 * 
	 * @param parent (Window) [optional] parent window
	 * @param x, y (int) [optional] coordinates
	 * @param width, height (int) [optional] control size.
	 */
	this.ImageButton = function(parent, x, y, width, height) {
		super(parent, x, y, width, height);
		this.images = {};
		this.getElement().setAttribute('unselectable', 'on');
		// Create preloading images.
		// TODO: use ImagePreloader
		var states = [ ImageButton.STATE_NORMAL, ImageButton.STATE_HOVER, ImageButton.STATE_PRESSED, ImageButton.STATE_DISABLED ];
		for (var i = 0; i < states.length; i++) {
			this.images[states[i]] = new window.Image();
		}
		this.setState(ImageButton.STATE_NORMAL);
	}
	
	/**
	 * Changes current button state.
	 *
	 * Use this method if you want to change your button view corresponding the specified state.
	 * NOTE: this method will be invoked automatically when the user interacts with the button
	 * by clicking on it or mousing over/out it.
	 *
	 * You can use setImages method to specify the images your buttons should have for each
	 * particular state. You can also style your buttons in pure CSS in any of separate ways:
	 *
	 * 1. Using state attribute
	 *
	 * #browse-button[state=normal] { background-image: url(/images/browse-normal.gif) }
	 * #browse-button[state=hover] { background-image: url(/images/browse-hover.gif) }
	 * #browse-button[state=pressed] { background-image: url(/images/browse-pressed.gif) }
 	 * #browse-button[state=disabled] { background-image: url(/images/browse-disabled.gif) }
 	 *
 	 * I hope in IE 7 will be possible to write something like above,
 	 * but for now it's supported only by FF :\
 	 *
 	 * 2. Using style names
 	 *
 	 * .YourButtonClass {
	 * 		[rules that will be applied to all-states buttons]
	 * }
	 * .YourButtonClass-pressed {
	 * 		[similar rules for pressed buttons]
	 * }
	 * ...
	 *
	 * @param state (int) new state.
	 */
	this.setState = function(state) {
		this.getElement().setAttribute('state', state);
		
		// Set the new style name
		this.removeStyleName(this.getStyleName() + '-' + ImageButton.states[this.state]);
		this.addStyleName(this.getStyleName() + '-' + ImageButton.states[state]);
		this.state = state;

		// Change the image if specified
		if (this.imageList) {
			this.setStyle('background-position', -(this.getWidth() * state) + 'px top');
		} else if (this.images[state].src.length > 0) {
			this.setImage(this.images[state].src);
		}
	}
	
	/**
	 * Returns current button state.
	 *
	 * @return int
	 */
	this.getState = function() {
		return this.state;
	}
	
	/**
	 * Sets URLs of images for this button.
	 *
	 * @param normal, hover, pressed, disabled (string) URLs of images.
	 */
	this.setImages = function(normal, hover, pressed, disabled) {
		if (normal)	this.images[ImageButton.STATE_NORMAL].src = normal;
		if (hover)		this.images[ImageButton.STATE_HOVER].src = hover;
		if (pressed)	this.images[ImageButton.STATE_PRESSED].src = pressed;
		if (disabled)	this.images[ImageButton.STATE_DISABLED].src = disabled;
		if (this.images[this.state].src.length > 0) this.setImage(this.images[this.state].src);
	}
	
	/**
	 * Sets the src of image which contains list of contatenated images.
	 * The image shoud contain parts in the following order:
	 * normal/hover/pressed/disabled.
	 * 
	 * @param src (string) image URL.
	 */
	this.setImageList = function(src) {
		if (!this.imageList)
			this.imageList = new window.Image();
			
		this.imageList.src = src;
		this.setImage(src);
		this.setStyle('background-position', -(this.getWidth() * this.state) + 'px top');
	}
	
	/**
	 * Sets image for button.
	 *
	 * @param source (string) image URL.
	 */
	this.setImage = function(source) {
		this.setStyle('background-image', 'url("' + source + '")');
	}
	
	/**
	 * Sets whether the button is enabled.
	 *
	 * @param enabled (bool) true if enabled, false otherwise.
	 */
	this.setEnabled = function(enabled) {
		if (enabled) {
			super.setEnabled(enabled);
			this.setState(ImageButton.STATE_NORMAL);
		} else {
			this.setState(ImageButton.STATE_DISABLED);
			super.setEnabled(enabled);
		}
	}

	this.onmousedown = function(event) {
		this.setState(ImageButton.STATE_PRESSED);
		this.setFocus(true);
		this.activate();
		event.stop();
		event.cancel();
	}
	
	this.onmouseover = this.onmouseup = function(event) {
		this.setState(ImageButton.STATE_HOVER);
		event.stop();
	}
	
	this.onmouseout = function(event) {
		this.setState(ImageButton.STATE_NORMAL);
		event.stop();
	}
	
	this.ondblclick = function(event) {
		event.stop();
	}
	
	this.onclick = function(event, targetWindow, currentWindow) {
		// Emulate oncommand event
		if ('function' == typeof this.oncommand) {
			this.oncommand(event, targetWindow, currentWindow);
		}
	}
	
	this.onkeydown = function(event, targetWindow, currentWindow) {
		if (Event.KEY_SPACE == event.keyCode) {
			event.stop();
			this.setState(ImageButton.STATE_PRESSED);
		} else if (Event.KEY_ENTER == event.keyCode) {
			event.stop();
			// Emulate oncommand event
			if ('function' == typeof this.oncommand) {
				this.oncommand(event, targetWindow, currentWindow);
			}
		}
	}
	
	this.onkeyup = function(event, targetWindow, currentWindow) {
		if (Event.KEY_SPACE == event.keyCode) {
			event.stop();
			this.setState(ImageButton.STATE_NORMAL);
			// Emulate oncommand event
			if ('function' == typeof this.oncommand) {
				this.oncommand(event, targetWindow, currentWindow);
			}
		}
	}
}

core.ui.ImageButton.STATE_NORMAL 	= 0;
core.ui.ImageButton.STATE_HOVER 	= 1;
core.ui.ImageButton.STATE_PRESSED 	= 2;
core.ui.ImageButton.STATE_DISABLED 	= 3;

core.ui.ImageButton.states = [ 'normal', 'hover', 'pressed', 'disabled' ];